package boot.demo.controller;

import boot.demo.event.EventA;
import boot.demo.event.EventB;
import cn.hutool.core.util.RandomUtil;
import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.Weigher;
import com.google.common.collect.*;
import com.google.common.eventbus.AsyncEventBus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/test")
public class TestController {

    private final List<String> stringList = Arrays.asList(
            "tom","jack","bob");

    private final List<String> stringListWithNullValue = Arrays.asList(
            "tom","jack","bob",null,"rose");

    private LoadingCache<String,String> cache;

    @Autowired
    AsyncEventBus eventBus;

    @PostMapping("/pushEvent")
    public void doPushEvent(){
        EventA eventA = new EventA();
        eventA.setMsg("Hey, gay!Event A Test");
        eventBus.post(eventA);
        EventB eventB = new EventB();
        eventB.setMsg("Hey, gay!Event B come");
        eventBus.post(eventB);
    }

    @PostMapping("/joiner")
    public String doJoiner(){
        String join = Joiner.on("#").join(stringList);
        String joinSkipNull = Joiner.on("#").skipNulls().join(stringListWithNullValue);
        String joinReplaceNull = Joiner.on("#").useForNull("NULL").join(stringListWithNullValue);
        final StringBuilder buffer = new StringBuilder("TEST");
        StringBuilder buffer_new = Joiner.on("#").appendTo(buffer, stringList);
        return  join + "     " + joinSkipNull + "     " + joinReplaceNull + "     " + buffer_new.toString();
    }

    @PostMapping("/spliter")
    public String doSpliter(){
        List<String> sl = Splitter.on("|").limit(4).trimResults().omitEmptyStrings().splitToList(" hello | word | t fgrtfg || 566| |");
        return  sl.toString();
    }

    @PostMapping("/CharMatcher")
    public void doCharMatcher(){
        //1.判定型函数，判断 CharMacher 和入参字符串的匹配关系。
        System.out.println(CharMatcher.is('a').matchesAllOf("aaa")); //true
        System.out.println(CharMatcher.is('a').matchesAnyOf("aba")); //true
        System.out.println(CharMatcher.is('a').matchesNoneOf("aba"));//false
        //2.计数型函数，查找入参字符串中第一次、最后一次出现目标字符的位置，或者目标字符出现的次数
        System.out.println(CharMatcher.is('a').countIn("aba"));//2
        System.out.println(CharMatcher.is('a').indexIn("aba"));//0
        //3.对匹配字符的操作。包括 removeFrom、retainFrom、replaceFrom、trimFrom、collapseFrom 等
        System.out.println(CharMatcher.is('a').retainFrom("bazaar"));//aaa
    }

    @PostMapping("/ImmutableSet")
    public void doImmutable(){
        List<String> list = Arrays.asList("a", "b", "c");
        ImmutableSet<String> strings = ImmutableSet.copyOf(list);
        strings.forEach(System.out::println);
    }

    @PostMapping("/SortedMultiset")
    public void doSortedMultiset(){
        SortedMultiset<String> sortedMultiset = TreeMultiset.create();
        sortedMultiset.add("a");
        sortedMultiset.add("b");
        sortedMultiset.add("c");
        sortedMultiset.add("d");
        sortedMultiset.add("e");
        SortedMultiset<String> strings = sortedMultiset.subMultiset("a", BoundType.CLOSED, "e", BoundType.OPEN);
        strings.forEach(System.out::print);
        strings.forEach(System.out::println);
    }

    @PostMapping("/multimap")
    public void doMultimap(){
        ArrayListMultimap<String, Integer> multimap = ArrayListMultimap.create();
        multimap.put("a", 1);
        multimap.put("a", 2);
        multimap.put("a", 3);
        multimap.put("a", 4);
        multimap.put("b", 1);
        System.out.println(multimap.size());

        //  asMap() 提供Map<K,Collection<V>>形式的视图 collections 中
        //  a->{1,2,3,4}
        //  b->{1}
        Collection<Collection<Integer>> collections = multimap.asMap().values();

        // values {1,2,3,4,1}
        Collection<Integer> values = multimap.values();

        Collection<Map.Entry<String, Integer>> entries = multimap.entries();
        entries.forEach(item -> {
            System.out.print("key--->" + item.getKey());
            System.out.println("  value--->" + item.getValue());
        });
    }

    @PostMapping("/Table")
    public void doTable(){
        Table<String, Integer, String> table = HashBasedTable.create();
        table.put("a", 1, "第一个值");
        table.put("a", 2, "第二个值");
        table.put("a", 3, "第三个值");
        table.put("b", 1, "第一个值");
        table.put("b", 4, "第四个值");

        Map<Integer, String> a = table.row("a");
        Map<Integer, String> b = table.row("b");
        Map<String, String> column = table.column(1);
        Set<Table.Cell<String, Integer, String>> cells = table.cellSet();
        Map<Integer, Map<String, String>> columnMap = table.columnMap();
        Collection<String> values = table.values();
        System.out.println("");
    }

    @PostConstruct
    public void init(){
         cache = CacheBuilder.newBuilder()
                .maximumWeight(1000)
                .weigher(new Weigher<String, String>() {
                    @Override
                    public int weigh(String key, String value) {
                        return key.length();
                    }
                })
                .expireAfterAccess(10, TimeUnit.SECONDS)
                .build(new CacheLoader<String, String>() {
                    @Override
                    public String load(String key) throws Exception {
                        return key + RandomUtil.randomString(12);
                    }
                });
        cache.put("test",RandomUtil.randomString(12));
    }

    @PostMapping("/cache")
    public String doCache() throws ExecutionException {
        return cache.get("test");
    }

    @PostMapping("/preCondition")
    public String doCheck(String val) throws ExecutionException {
        return Preconditions.checkNotNull(val, "空字符串");
    }
}
